package com.kinghood.productcenter.service.base.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kinghood.infrastructure.api.authority.SysLogModuleEnum;
import com.kinghood.infrastructure.api.authority.UserRemoteVo;
import com.kinghood.infrastructure.model.KingHoodException;
import com.kinghood.infrastructure.model.constant.CommonConstants;
import com.kinghood.infrastructure.model.enums.StatusEnum;
import com.kinghood.infrastructure.util.base.IdGenUtil;
import com.kinghood.infrastructure.util.UserUtil;
import com.kinghood.infrastructure.util.excel.EasyExcelUtil;
import com.kinghood.productcenter.common.api.authority.UserRemote;
import com.kinghood.productcenter.common.model.dao.base.BaseSupplierDO;
import com.kinghood.infrastructure.model.dto.SortReqDTO;
import com.kinghood.infrastructure.model.dto.StatusReqDTO;
import com.kinghood.productcenter.common.model.dao.product.DownloadCenterDO;
import com.kinghood.productcenter.common.model.dao.product.ProductSkuSupplierBaseDO;
import com.kinghood.productcenter.common.model.dto.base.ListSupplierQueryDTO;
import com.kinghood.productcenter.common.model.dto.base.SupplierReqDTO;
import com.kinghood.productcenter.common.model.excel.SupplierExcel;
import com.kinghood.productcenter.common.model.vo.base.SupplierVO;
import com.kinghood.productcenter.common.utils.UserNameUtil;
import com.kinghood.productcenter.dao.base.BaseSupplierMapper;
import com.kinghood.productcenter.service.async.IAsyncHuaWeiYunService;
import com.kinghood.productcenter.service.base.IBaseSupplierService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kinghood.productcenter.service.product.IDownloadCenterService;
import com.kinghood.productcenter.service.product.IProductSkuSupplierBaseService;
import com.kinghood.productcenter.service.product.handler.ProductBaseHandler;
import com.kinghood.sharding.model.BasePage;
import com.kinghood.sharding.model.KingHoodPageUtil;
import com.kinghood.sharding.model.KingPageResult;
import com.kinghood.sharding.model.PageResponseVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 基础选项-供应商 服务实现类
 * </p>
 *
 * @author KingHood
 * @since 2023-12-20
 */
@Service
public class BaseSupplierServiceImpl extends ServiceImpl<BaseSupplierMapper, BaseSupplierDO> implements IBaseSupplierService {
    @Value("${base.uploadPath}")
    private String uploadPath;
    @Resource
    private UserRemote userRemote;
    @Resource
    private IDownloadCenterService downloadCenterService;
    @Resource
    private IProductSkuSupplierBaseService productSkuSupplierBaseService;
    @Resource
    private IAsyncHuaWeiYunService asyncUploadHuaWeiYun;

    /**
     * 更新供应商状态
     *
     * @param param 参数
     * @return
     * @author jp
     * @date 2024/01/12 14:57
     */
    @Override
    public void updateSupplierStatus(StatusReqDTO param) {
        this.lambdaUpdate().set(BaseSupplierDO::getStatus, param.getStatus())
                .set(BaseSupplierDO::getUpdateTime, LocalDateTime.now())
                .set(BaseSupplierDO::getUpdateUserId, UserUtil.getUserId())
                .eq(BaseSupplierDO::getId, param.getId())
                .eq(BaseSupplierDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .update();
    }

    /**
     * 更新供应商排序
     *
     * @param param 参数
     * @return
     * @author jp
     * @date 2024/01/12 14:57
     */
    @Override
    public void updateSupplierSort(SortReqDTO param) {
        this.lambdaUpdate().set(BaseSupplierDO::getSort, param.getSort())
                .set(BaseSupplierDO::getUpdateTime, LocalDateTime.now())
                .set(BaseSupplierDO::getUpdateUserId, UserUtil.getUserId())
                .eq(BaseSupplierDO::getId, param.getId())
                .eq(BaseSupplierDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .update();
    }

    /**
     * 删除
     *
     * @param id 身份证件
     * @return
     * @author jp
     * @date 2024/01/12 14:57
     */
    @Override
    public void delSupplierById(Long id) {
        BaseSupplierDO supplier = this.getById(id);
        if (Objects.nonNull(supplier) && !supplier.getStatus().equals(CommonConstants.DISABLE)) {
            throw new KingHoodException(-1 , "只有停用状态的才可操作删除");
        }
        long count = productSkuSupplierBaseService.lambdaQuery().eq(ProductSkuSupplierBaseDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .eq(ProductSkuSupplierBaseDO::getSupplierId, id)
                .count();
        if (count > 0) {
            throw new KingHoodException(-1, "存在关联商品，请移除后再删");
        }
        this.lambdaUpdate().set(BaseSupplierDO::getIsDelete, CommonConstants.IS_DELETE_Y)
                .set(BaseSupplierDO::getUpdateTime, LocalDateTime.now())
                .set(BaseSupplierDO::getUpdateUserId, UserUtil.getUserId())
                .eq(BaseSupplierDO::getId, id)
                .eq(BaseSupplierDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .update();
    }

    /**
     * 添加或更新供应商
     *
     * @param param 参数
     * @return
     * @author jp
     * @date 2024/01/12 14:57
     */
    public void addOrUpdateSupplier(SupplierReqDTO param) {
        checkOnly(param);
        BaseSupplierDO supplier = new BaseSupplierDO();
        BeanUtils.copyProperties(param, supplier);
        if (Objects.isNull(param.getId())) {
            supplier.setId(IdGenUtil.get().nextId());
            supplier.setCreateTime(LocalDateTime.now());
            supplier.setCreateUserId(UserUtil.getUserId());
            this.save(supplier);
        } else {
            supplier.setUpdateTime(LocalDateTime.now());
            supplier.setUpdateUserId(UserUtil.getUserId());
            this.updateById(supplier);
        }
    }

    /**
     * 检查是否唯一
     *
     * @param param 参数
     * @author jp
     * @date 2023/12/21
     */
    private void checkOnly(SupplierReqDTO param){
        Long count;
        if (Objects.isNull(param.getId())) {
            count = this.lambdaQuery().eq(BaseSupplierDO::getSupplierCode, param.getSupplierCode())
                    .eq(BaseSupplierDO::getIsDelete, CommonConstants.IS_DELETE_N)
                    .count();
            if (count > 0) {
                throw new KingHoodException(-1 ,"编码已存在");
            }
        } else {
            count = this.lambdaQuery().eq(BaseSupplierDO::getSupplierCode, param.getSupplierCode())
                    .ne(BaseSupplierDO::getId, param.getId())
                    .eq(BaseSupplierDO::getIsDelete, CommonConstants.IS_DELETE_N)
                    .count();
            if (count > 0) {
                throw new KingHoodException(-1 ,"编码已存在");
            }
        }
    }

    /**
     * 供应商列表
     *
     * @param param 参数
     * @return @return {@link PageResponseVO }
     * @author jp
     * @date 2024/01/12 14:57
     */
    @Override
    public PageResponseVO listSupplier(ListSupplierQueryDTO param) {
        Page<SupplierVO> result = this.baseMapper.listSupplier(KingHoodPageUtil.getPage(param, param), param);

        Set<Long> userIdList = new HashSet<>();
        for (SupplierVO record : result.getRecords()) {
            userIdList.add(record.getCreateUserId());
            userIdList.add(record.getUpdateUserId());
            record.setStatusTxt(StatusEnum.getNameByStatus(record.getStatus()));
        }
        userIdList.remove(null);
        if (!CollectionUtils.isEmpty(userIdList)) {
            Map<Long, UserRemoteVo> userMap = userRemote.getUserByIds(new ArrayList<Long>(userIdList));
            for (SupplierVO record : result.getRecords()) {
                record.setCreateUserName(UserNameUtil.getName(record.getCreateUserId(), userMap));
                record.setUpdateUserName(UserNameUtil.getName(record.getUpdateUserId(), userMap));
            }
        }
        return KingPageResult.getResult(result);
    }

    /**
     * 供应商详情
     *
     * @param id 身份证件
     * @return @return {@link SupplierVO }
     * @author jp
     * @date 2024/01/12 14:58
     */
    @Override
    public SupplierVO detailSupplier(Long id) {
        SupplierVO result=new SupplierVO();
        BaseSupplierDO supplier = this.lambdaQuery().eq(BaseSupplierDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .eq(BaseSupplierDO::getId, id)
                .one();
        if (Objects.nonNull(supplier)) {
            BeanUtils.copyProperties(supplier, result);
            return result;
        }
        return null;
    }

    /**
     * 下载供应商
     *
     * @param param    参数
     * @param response 回答
     * @author jp
     * @date 2024/01/04
     */
    @Override
    public void downloadSupplier(ListSupplierQueryDTO param, HttpServletResponse response) {
        String fileName = StringUtils.isEmpty(param.getFileName()) ? "供应商数据" : param.getFileName();
        String sheetName = StringUtils.isEmpty(param.getSheetName()) ? "供应商" : param.getSheetName();

        if (Objects.isNull(param.getPage())) {
            param.setPage(new BasePage());
            param.getPage().setPageSize(99999);
        }
        PageResponseVO responseVO = listSupplier(param);
        List<SupplierVO> dataList = responseVO.getList();
        List<SupplierExcel> result = new ArrayList<>();
        for (SupplierVO supplierVO : dataList) {
            SupplierExcel excel = new SupplierExcel();
            BeanUtils.copyProperties(supplierVO, excel);
            result.add(excel);
        }
        // 保存到数据库
        LocalDateTime now = LocalDateTime.now();
        DownloadCenterDO downloadCenterDO = new DownloadCenterDO();
        try {
            String showParam = "";
            if (!CollectionUtils.isEmpty(param.getDownloadField())) {
                showParam = String.join(",", param.getDownloadField());
            }
            String path = EasyExcelUtil.export(response, fileName, sheetName, result, SupplierExcel.class,
                    showParam, uploadPath);
            File file = new File(path);
            downloadCenterDO.setId(IdGenUtil.getId())
                    .setFileName(file.getName())
                    .setModule(SysLogModuleEnum.PRODUCT_SUPPLIER.getType())
                    .setType(2)
                    .setFileSize(ProductBaseHandler.getSizeName(file.length()))
                    .setUrl(path)
                    .setCreateTime(now)
                    .setUpdateTime(now)
                    .setCreateUserId(UserUtil.getUserId())
                    .setUpdateUserId(UserUtil.getUserId());
            downloadCenterService.save(downloadCenterDO);
            asyncUploadHuaWeiYun.uploadToHuaWeiYun(downloadCenterDO.getId(), file.getAbsolutePath());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
